﻿
//using Rokae_net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NetTopologySuite.Mathematics;
using System.Drawing.Drawing2D;

using Dtt_PLClibrary.ModBus;
using Matrix = System.Drawing.Drawing2D.Matrix;
using Microsoft.Win32;

namespace txtTEST
{
    public partial class Form3 : Form
    {
        public Form3()
        {
            InitializeComponent();

            dataSet1.Tables[0].Namespace = "H-789";
            //dataSet1.Tables[0].Rows.Add();
            //ReadSettingData();
            //var buf_data = GetSettingValue("Table1", "maxSpeed");
            ;

            double angle = 0;
            PointF[] points1 = new PointF[1];
            PointF[] points2 = new PointF[1];
            PointF[] points3 = new PointF[1];
            points1[0] = new PointF(5f,5f);

            Matrix _M = new Matrix();
            //旋转
            _M.Rotate(90.0F, MatrixOrder.Append);
            //_M.RotateAt(90.0F, new PointF(0,0), MatrixOrder.Append);
            _M.TransformPoints(points1);

            points2[0].X = 5.0f - points1[0].X;
            points2[0].Y = 5.0f - points1[0].Y;

            //平移
            //_M.Translate(points2[0].X, points2[0].Y, MatrixOrder.Append);
            _M.Translate(2, 2, MatrixOrder.Append);
            _M.TransformPoints(points1);

            ;


        }

        private void button2_Click(object sender, EventArgs e)
        {
            //var buf = GetSettingValue("Table1", "maxSpeed");

            WriteSettingData();
            ;



            //PointF A = new PointF(11.23f, 18.99f);
            //PointF B = new PointF(8.02f, 27.15f);
            //PointF C = new PointF(10.15f, 33.98f);

            //PointF center = calculate_circle_center(A, B, C);
            //double radius = calculate_radius(A, B, center);

            //Point3D A3 = new Point3D(11.23f, 18.99f, 1.0f);
            //Point3D B3 = new Point3D(8.02f, 27.15f, 0.0f);
            //Point3D C3 = new Point3D(10.15f, 33.98f, 1.0f);

            //double radius3 = 0;
            //Point3D buf = calc_arc_bypoints3(A3, B3, C3, out radius3);
            ;

        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if ((e.KeyChar < 48 || e.KeyChar > 57) && e.KeyChar != 8)
            {
                e.Handled = true;
            }

        }
        private void textBox1_KeyUp(object sender, KeyEventArgs e)
        {
            
            ;
        }
        public void WriteSettingData()
        {
            string sSettingDataPath = String.Format("{0}\\{1}.xml", "HU", "KL");
            FileInfo fileInfo = new FileInfo(sSettingDataPath);
            if (fileInfo.Directory.Exists == false)
            {
                fileInfo.Directory.Create();
            }
            dataSet1.AcceptChanges();
            dataSet1.WriteXml(sSettingDataPath);
        }

        public void ReadSettingData()
        {
            dataSet1.Clear();
            string sSettingDataPath = String.Format("{0}\\{1}.xml", "HU", "KL");
            if (File.Exists(sSettingDataPath))
            {
                dataSet1.ReadXml(sSettingDataPath);
            }
            for (int i = 0; i < dataSet1.Tables.Count; i++)
            {
                if (dataSet1.Tables[i].Rows.Count == 0)
                {
                    DataRow NewRow = dataSet1.Tables[i].NewRow();
                    //for (int j = 0; j < SettingData.Tables[i].Columns.Count; j++)
                    //    NewRow[j] = GetInitialValue(SettingData.Tables[i].Columns[j].DataType);
                    dataSet1.Tables[i].Rows.Add(NewRow);
                }
            }
            dataSet1.AcceptChanges();
        }

        public dynamic GetSettingValue(string TableName, string ColumnName, int RowIndex = 0)
        {
            dynamic Value = null;
            if (dataSet1.Tables[TableName].Columns.IndexOf(ColumnName) >= 0)
            {
                Value = dataSet1.Tables[TableName].Rows[RowIndex][ColumnName, DataRowVersion.Original];
                if (Value.ToString() == "")
                {
                    Value = GetDefaultValue(dataSet1.Tables[TableName].Columns[ColumnName].DataType);
                }
            }
            return Value;
        }

        private dynamic GetDefaultValue(Type tp)
        {
            dynamic dmc = null;
            if (tp == typeof(Boolean))
                dmc = false;
            else if (tp == typeof(Int16))
                dmc = 0;
            else if (tp == typeof(Int32))
                dmc = 0;
            else if (tp == typeof(Int64))
                dmc = 0;
            else if (tp == typeof(double))
                dmc = 0;
            else if (tp == typeof(byte))
                dmc = 0;
            else if (tp == typeof(string))
                dmc = "";
            return dmc;
        }


        [DllImport("gdi32.dll", SetLastError = true)]
        private static extern bool DeleteObject(IntPtr hObject);


        ModbusRtu _ModbusRtu = new ModbusRtu(1);//站号

        private void Form3_Load(object sender, EventArgs e)
        {



            //_ModbusRtu.SerialPortInni("COM4", 9600, 8, StopBits.None, Parity.None);//初始化端口
            //_ModbusRtu.ReceiveTimeout = 3000;//读超时
            //_ModbusRtu.Open();//打开端口

            ////读取
            //float str100 =  _ModbusRtu.ReadFloat("100").Content;//，获取浮点地址为十进制
            //Int16[] ushort100 = _ModbusRtu.ReadInt16("120", (ushort)10).Content;
            //int[] int100 = _ModbusRtu.ReadInt32("120", (ushort)10).Content;
            //int int102 = _ModbusRtu.ReadInt32("120").Content;

            //_ModbusRtu.IsStringReverse = false;

            //_ModbusRtu.DataFormat = Dtt_PLClibrary.Core.DataFormat.ABCD;


            ////写入

            //Dtt_PLClibrary.OperateResult _operateResult  =_ModbusRtu.Write("100", true);// 写入线圈100为通
            //if (_operateResult.IsSuccess)
            //{
            //    ;// 写入成功
            //}

            //_ModbusRtu.Write("100", (short)12345);//  
            //_ModbusRtu.Write("100", (int)12345);//  

            //ushort[] data = new ushort[10];
            //_ModbusRtu.Write("100", data);//  

        }
        private void Form3_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (_ModbusRtu.IsOpen())
            {
                _ModbusRtu.Close();//关闭端口
            }

        }




        public void SetAutoStart(string keyName, string exePath)
        {
            RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
            registryKey.SetValue(keyName, exePath);
        }



        #region //3点坐标，求点到平面距离
        //已知3点坐标，求平面ax+by+cz+d=0;
        public double[] find_plane(Position position_a, Position position_b, Position position_c)
        {
            try
            {
                double[] buf = new double[4];

                // 计算向量AB和AC
                double[] AB = new double[3] { position_b.X - position_a.X, position_b.Y - position_a.Y, position_b.Z - position_a.Z };
                double[] AC = new double[3] { position_c.X - position_a.X, position_c.Y - position_a.Y, position_c.Z - position_a.Z };

                // 计算平面的法向量
                double[] n = new double[3];
                n[0] = AB[1] * AC[2] - AB[2] * AC[1];
                n[1] = AB[2] * AC[0] - AB[0] * AC[2];
                n[2] = AB[0] * AC[1] - AB[1] * AC[0];

                // 计算平面方程的常数项
                double d = -(n[0] * position_a.X + n[1] * position_a.Y + n[2] * position_a.Z);

                // 如果叉积为零向量，则说明三个点共线或重合，无法确定平面。否则可以确定平面方程。
                if (n[0] == 0 && n[1] == 0 && n[2] == 0)
                {
                    return new double[4]; ;//("无法确定平面。\n");
                }
                else
                {
                    // 根据叉积向量的模长和方向确定平面方程参数a、b、c。
                    double aa = n[0] / Math.Sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
                    double bb = n[1] / Math.Sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
                    double cc = n[2] / Math.Sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
                    ;
                }
                buf[0] = n[0];
                buf[1] = n[1];
                buf[2] = n[2];
                buf[3] = d;
                return buf;
            }
            catch
            {
                return null;
            }
        }


        // 已知三点坐标，求法向量
        public double[] get_Normal(Position p1, Position p2, Position p3)
        {
            double a = (p2.Y - p1.Y) * (p3.Z - p1.Z) - (p2.Z - p1.Z) * (p3.Y - p1.Y);
            double b = (p2.Z - p1.Z) * (p3.X - p1.X) - (p2.X - p1.X) * (p3.Z - p1.Z);
            double c = (p2.X - p1.X) * (p3.Y - p1.Y) - (p2.Y - p1.Y) * (p3.X - p1.X);

            return new double[3] { a, b, c };
        }

        //点到平面距离
        public double dis_pt2panel(Position pt, double a, double b, double c, double d)
        {
            return Math.Abs(a * pt.X + b * pt.Y + c * pt.Z + d) / Math.Sqrt(a * a + b * b + c * c);
        }

        //多点坐标，求法向量
        public double[] calculatePlaneNormal(Position[] position)
        {
            double[] buf = new double[4];

            double x = 0, y = 0, z = 0, xy = 0, xz = 0, yz = 0, x2 = 0, y2 = 0, z2 = 0;
            for (int i = 0; i < position.Length; ++i)
            {
                x += position[i].X;
                y += position[i].Y;
                z += position[i].Z;
                xy += position[i].X * position[i].Y;
                xz += position[i].X * position[i].Z;
                yz += position[i].Y * position[i].Z;
                x2 += position[i].X * position[i].X;
                y2 += position[i].Y * position[i].Y;
                z2 += position[i].Z * position[i].Z;
            }
            double m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12;
            m1 = x2;
            m2 = xy;
            m3 = xz;
            m4 = x;
            m5 = xy;
            m6 = y2;
            m7 = yz;
            m8 = y;
            m9 = xz;
            m10 = yz;
            m11 = z2;
            m12 = z;
            double n1, n2, n3, n4, n5, n6;
            n1 = m5 * m3 - m1 * m7;
            n2 = m6 * m3 - m2 * m7;
            n3 = m8 * m3 - m4 * m7;
            n4 = m9 * m3 - m1 * m11;
            n5 = m10 * m3 - m2 * m11;
            n6 = m12 * m3 - m4 * m11;
            buf[0] = (n6 * n2 - n3 * n5) / (n1 * n5 - n4 * n2);
            buf[1] = (-n3 - buf[0] * n1) / n2;
            buf[2] = (-m4 - buf[0] * m1 - buf[1] * m2) / m3;

            buf[3] = -(buf[0] * position[0].X + buf[1] * position[0].Y + buf[2] * position[0].Z);

            return buf;
        }

        //三个点计算平面参数
        public double[] get_panel(Point3D p1, Point3D p2, Point3D p3)
        {
            double[] plane_data = new double[4];
            plane_data[0] = (p2.y - p1.y) * (p3.z - p1.z) - (p2.z - p1.z) * (p3.y - p1.y);//a
            plane_data[1] = (p2.z - p1.z) * (p3.x - p1.x) - (p2.x - p1.x) * (p3.z - p1.z);//b
            plane_data[2] = (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x);//c
            plane_data[3] = 0 - (plane_data[0] * p1.x + plane_data[1] * p1.y + plane_data[2] * p1.z);//d

            return plane_data;
        }

        //已知两点计算其中垂面的参数
        public double[] get_vertical_plane(Point3D p1, Point3D p2)
        {
            double[] plane_data = new double[4];
            plane_data[0] = p2.x - p1.x;
            plane_data[1] = p2.y - p1.y;
            plane_data[2] = p2.z - p1.z;
            plane_data[3] = 0 - 0.5 * (p2.x * p2.x - p1.x * p1.x + p2.y * p2.y - p1.y * p1.y + p2.z * p2.z - p1.z * p1.z);
            return plane_data;
        }

        #endregion


        #region //三点计算圆坐、半径        
        public class Position
        {
            public double X;
            public double Y;
            public double Z;
            public Position()
            {
                X = 0;
                Y = 0;
                Z = 0;
            }
            public Position(double _X, double _Y, double _Z)
            {
                X = _X;
                Y = _Y;
                Z = _Z;
            }
        }

        //三点计算圆坐标（平面）
        public PointF calculate_circle_center(PointF p1, PointF p2, PointF p3)
        {
            float D = 2 * (p1.X * (p2.Y - p3.Y) + p2.X * (p3.Y - p1.Y) + p3.X * (p1.Y - p2.Y));
            float Ux = ((p1.X * p1.X + p1.Y * p1.Y) * (p2.Y - p3.Y) + (p2.X * p2.X + p2.Y * p2.Y) * (p3.Y - p1.Y) + (p3.X * p3.X + p3.Y * p3.Y) * (p1.Y - p2.Y)) / D;
            float Uy = ((p1.X * p1.X + p1.Y * p1.Y) * (p3.X - p2.X) + (p2.X * p2.X + p2.Y * p2.Y) * (p1.X - p3.X) + (p3.X * p3.X + p3.Y * p3.Y) * (p2.X - p1.X)) / D;

            return new PointF(Ux, Uy);
        }
        //计算半径
        public double calculate_radius(PointF p1, PointF p2, PointF center)
        {
            double dx = center.X - p1.X;
            double dy = center.Y - p1.Y;
            return Math.Sqrt(dx * dx + dy * dy);
        }

        public class Point3D
        {
            public double x;
            public double y;
            public double z;
            public Point3D()
            {
                x = 0;
                y = 0;
                z = 0;
            }
            public Point3D(double _x, double _y, double _z)
            {
                x = _x;
                y = _y;
                z = _z;
            }
        }
        public class Point2D
        {
            public double x;
            public double y;
        }

        //三点计算圆坐标(空间)
        public Point2D circleCenter(Point3D p1, Point3D p2, Point3D p3)
        {
            Point2D center = new Point2D();
            center.x = (p1.x + p2.x + p3.x) / 3;
            center.y = (p1.y + p2.y + p3.y) / 3;
            return center;
        }

        public double circleRadius(Point3D p1, Point3D p2, Point3D p3)
        {
            Point2D center = circleCenter(p1, p2, p3);
            double dx = p2.x - p1.x;
            double dy = p2.y - p1.y;
            double dr = p2.z - p1.z;

            double a = dx * dx + dy * dy + dr * dr;
            double b = 2 * (dx * (p1.x + p2.x) + dy * (p1.y + p2.y) + dr * (p1.z + p2.z));
            double c = (p1.x + p2.x) * (p1.x + p2.x) + (p1.y + p2.y) * (p1.y + p2.y) + (p1.z + p2.z) * (p1.z + p2.z) - center.x * center.x - center.y * center.y;

            double radius = Math.Sqrt(b * b - 4 * a * c) / (2 * a);
            return radius;
        }

        public Point3D calc_arc_bypoints3(Point3D points0, Point3D points1, Point3D points2, out double radius)
        {
            try
            {
                double x1 = points0.x, x2 = points1.x, x3 = points2.x;
                double y1 = points0.y, y2 = points1.y, y3 = points2.y;
                double z1 = points0.z, z2 = points1.z, z3 = points2.z;

                double a1 = (y1 * z2 - y2 * z1 - y1 * z3 + y3 * z1 + y2 * z3 - y3 * z2),
                       b1 = -(x1 * z2 - x2 * z1 - x1 * z3 + x3 * z1 + x2 * z3 - x3 * z2),
                       c1 = (x1 * y2 - x2 * y1 - x1 * y3 + x3 * y1 + x2 * y3 - x3 * y2),
                       d1 = -(x1 * y2 * z3 - x1 * y3 * z2 - x2 * y1 * z3 + x2 * y3 * z1 + x3 * y1 * z2 - x3 * y2 * z1);

                double a2 = 2 * (x2 - x1),
                       b2 = 2 * (y2 - y1),
                       c2 = 2 * (z2 - z1),
                       d2 = x1 * x1 + y1 * y1 + z1 * z1 - x2 * x2 - y2 * y2 - z2 * z2;

                double a3 = 2 * (x3 - x1),
                       b3 = 2 * (y3 - y1),
                       c3 = 2 * (z3 - z1),
                       d3 = x1 * x1 + y1 * y1 + z1 * z1 - x3 * x3 - y3 * y3 - z3 * z3;

                double xyz_dev = a1 * b2 * c3 - a1 * b3 * c2 - a2 * b1 * c3 + a2 * b3 * c1 + a3 * b1 * c2 - a3 * b2 * c1;
                if (xyz_dev < 1e-6f)
                {
                    radius = 0;
                    return null;
                }

                Point3D buf = new Point3D();
                buf.x = -(b1 * c2 * d3 - b1 * c3 * d2 - b2 * c1 * d3 + b2 * c3 * d1 + b3 * c1 * d2 - b3 * c2 * d1) / xyz_dev;
                buf.y = (a1 * c2 * d3 - a1 * c3 * d2 - a2 * c1 * d3 + a2 * c3 * d1 + a3 * c1 * d2 - a3 * c2 * d1) / xyz_dev;
                buf.z = -(a1 * b2 * d3 - a1 * b3 * d2 - a2 * b1 * d3 + a2 * b3 * d1 + a3 * b1 * d2 - a3 * b2 * d1) / xyz_dev;

                radius = Math.Sqrt(Math.Pow((points0.x - buf.x), 2) + Math.Pow((points0.y - buf.y), 2) + Math.Pow((points0.z - buf.z), 2));
                return buf;
            }
            catch
            {
                radius = 0;
                return null;
            }

        }




        #endregion







        [DllImport("LGDETECT.dll", EntryPoint = "LGValueGet", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
        private static extern int LGValueGet(IntPtr dataTFT, int rowTFT, int colTFT, int channel, out double RValue, out double GValue, out double BValue, out double lightValue);



        private void button1_Click(object sender, EventArgs e)
        {

            //int a= RokaeAPI.Rokae_API_Init("127.0.0.1",9600);

            Image buf_img3 = getImage(@"C:\Users\zhang\Desktop\DGGG.png");


            IntPtr ptr = IntPtr.Zero;
            Bitmap buf_img = new Bitmap(@"C:\Users\zhang\Desktop\DGGG.png");
            Rectangle rect = new Rectangle(0, 0, buf_img.Width, buf_img.Height);
            BitmapData bmpData = buf_img.LockBits(rect, ImageLockMode.ReadWrite, buf_img.PixelFormat);
            ptr = bmpData.Scan0;

            double RValue = 0, GValue = 0, BValue = 0, lightValue = 0;
            int h_LGV = LGValueGet(ptr, bmpData.Width, bmpData.Height, 1, out RValue, out GValue, out BValue, out lightValue);

            buf_img.UnlockBits(bmpData);
            ;


            ////int bytes = bmpData.Stride * buf_img.Height;
            ////byte[] rgbValues = new byte[bytes];
            ////Marshal.Copy(ptr, rgbValues, 0, bytes);
            ////for (int counter = 0; counter < rgbValues.Length; counter += 3)
            ////    rgbValues[counter] = 255;
            ////Marshal.Copy(rgbValues, 0, ptr, bytes);

            IntPtr ptr_buf = buf_img.GetHbitmap();
            Bitmap PImage = Image.FromHbitmap(ptr_buf);

            DeleteObject(ptr_buf);

            ////IntPtr input = Marshal.AllocHGlobal(ptr);
            ////string str = Marshal.PtrToStringAnsi(input);


            //Bitmap bmp = new Bitmap(buf_img.Width, buf_img.Height, bmpData.Stride, buf_img.PixelFormat, ptr_buf);
            //ColorPalette cp = bmp.Palette;
            //// init palette
            ////for (int i = 0; i < 256; i++)
            ////{
            ////    cp.Entries[i] = Color.FromArgb(i, i, i);
            ////}
            //// set palette back
            //bmp.Palette = cp;
            //pictureBox1.Invalidate();



            //pictureBox1.Image = (Image)bmp;



            //buf_img.UnlockBits(bmpData);
        }










        private void Mono8ToBitmap(int Width, int Height, IntPtr pointer)
        {
            Bitmap bmp = new Bitmap(Width, Height, Width * 1, PixelFormat.Format32bppArgb, pointer);
            ColorPalette cp = bmp.Palette;
            // init palette
            for (int i = 0; i < 256; i++)
            {
                cp.Entries[i] = Color.FromArgb(i, i, i);
            }
            // set palette back
            bmp.Palette = cp;
            pictureBox1.Invalidate();


             


        }

        object image_obj = new object();
        private Image getImage(string path)
        {
            lock (image_obj)
            {
                Image Image_buf = null;
                try
                {
                    if (!File.Exists(path))
                    {
                        return null;
                    }
                    using (FileStream image = new FileStream(path, FileMode.Open))
                    {
                        Image_buf = (Image)Image.FromStream(image, true).Clone();
                    }
                    return Image_buf;
                }
                catch (Exception er)
                {
                    return null;
                }
            }
        }




    }
}
